package com.uduemc.biso.node.web.api.controller;

import cn.hutool.core.util.StrUtil;
import com.uduemc.biso.core.utils.JsonResult;
import com.uduemc.biso.node.web.api.dto.RequestHostBackupRestoreAmBackupList;
import com.uduemc.biso.node.web.api.dto.RequestHostBackupRestoreHmBackupList;
import com.uduemc.biso.node.web.api.pojo.ResponseBackupSetup;
import com.uduemc.biso.node.web.api.service.HostBackupRestoreService;
import com.uduemc.biso.node.web.api.service.HostSetupService;
import com.uduemc.biso.node.web.api.service.hostsetup.HSFuncService;
import io.swagger.annotations.*;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.io.IOException;

@RestController
@RequestMapping("/api/host-backup-restore")
@Api(tags = "站点备份还原模块")
public class HostBackupRestoreController {

    @Resource
    private HSFuncService hSFuncServiceImpl;

    @Resource
    private HostBackupRestoreService hostBackupRestoreServiceImpl;

    @Resource
    private HostSetupService hostSetupServiceImpl;

    @PostMapping("/next-backup-date")
    @ApiOperation(value = "获取下一次备份的日期", notes = "如果未开启备份，则返回的 data 内容为 null")
    public JsonResult nextBackupDate() throws IOException {
        return hostBackupRestoreServiceImpl.nextBackupDate();
    }

    @PostMapping("/next-backup-date-by-param")
    @ApiOperation(value = "通过参数，获取下一次备份的日期", notes = "如果未开启备份，则返回的 data 内容为 null。参数同 更新自动备份配置 （/update-backup-setup）。")
    public JsonResult nextBackupDateByParam(@Valid @RequestBody ResponseBackupSetup backupSetup, BindingResult errors) {
        if (errors.hasErrors()) {
            for (FieldError fieldError : errors.getFieldErrors()) {
                String defaultMessage = fieldError.getDefaultMessage();
                return JsonResult.messageError(defaultMessage);
            }
        }
        return hostBackupRestoreServiceImpl.nextBackupDateByParam(backupSetup);
    }

    @PostMapping("/default-backup-filename")
    @ApiOperation(value = "默认备份名称", notes = "返回系统默认整站数据备份名称")
    public JsonResult defaultBackupFilename() throws IOException {
        return hostBackupRestoreServiceImpl.defaultBackupFilename();
    }

    @PostMapping("/isbackup")
    @ApiOperation(value = "是否拥有备份权限", notes = "该站点是否拥有备份的增值功能权限， 0-没有，1-拥有")
    public JsonResult isbackup() {
        return JsonResult.ok(hSFuncServiceImpl.backupFunc() ? 1 : 0);
    }

    @PostMapping("/hm-backup-list")
    @ApiOperation(value = "手动备份的数据列表")
    @ApiResponses({@ApiResponse(code = 200, message = "data 中数据列表说明如下\n" + "total 检索得到的数据总数，rows 数据列表，以下数据字段说明。\n" + "id:数据ID，删除、还原备份数据时使用。\n"
            + "filename:手动或自动备份时，对备份用户或系统定义的备份名。\n" + "size:备份数据占用磁盘空间大小 byte。\n" + "description:手动备份时客户对备份数据输入的详细说明。\n"
            + "status:备份执行状态 0-未开始 1-成功 2-执行中 3-异常失败。\n" + "backupErrmsg:对于执行自动备份失败原因，备份成功该字段为空。\n" + "createAt:创建备份数据记录的时间。\n")})
    public JsonResult hmBackupList(@RequestBody RequestHostBackupRestoreHmBackupList hostBackupRestoreHmBackupList) throws IOException {
        return hostBackupRestoreServiceImpl.hmBackupList(hostBackupRestoreHmBackupList);
    }

    @PostMapping("/am-backup-list")
    @ApiOperation(value = "自动备份的数据列表")
    @ApiResponses({@ApiResponse(code = 200, message = "data 中数据列表说明同 手动备份的数据列表 （/hm-backup-list）")})
    public JsonResult amBackupList(@RequestBody RequestHostBackupRestoreAmBackupList hostBackupRestoreAmBackupList) throws IOException {
        return hostBackupRestoreServiceImpl.amBackupList(hostBackupRestoreAmBackupList);
    }

    @PostMapping("/backup-setup")
    @ApiOperation(value = "自动备份配置", response = ResponseBackupSetup.class)
    @ApiResponses({@ApiResponse(code = 200, message = "data 同 更新自动备份配置（/update-backup-setup） 请求的参数！")})
    public JsonResult backupSetup() throws IOException {
        return hostBackupRestoreServiceImpl.backupSetup();
    }

    @PostMapping("/update-backup-setup")
    @ApiOperation(value = "更新自动备份配置", notes = "返回同 自动备份配置 （/backup-setup）")
    public JsonResult updateBackupSetup(@Valid @RequestBody ResponseBackupSetup backupSetup, BindingResult errors) throws IOException {
        boolean backupFunc = hSFuncServiceImpl.backupFunc();
        if (!backupFunc) {
            return JsonResult.messageError("无权使用备份功能，请购买增值！");
        }
        if (errors.hasErrors()) {
            for (FieldError fieldError : errors.getFieldErrors()) {
                String defaultMessage = fieldError.getDefaultMessage();
                return JsonResult.messageError(defaultMessage);
            }
        }

        return hostBackupRestoreServiceImpl.updateBackupSetup(backupSetup);
    }

    /**
     * 异步备份，日志写到了 hostBackupRestoreServiceImpl 中
     */
    @PostMapping("/backup")
    @ApiOperation(value = "备份", notes = "异步，立即手动备份功能，返回中没有data内容。")
    @ApiImplicitParams({@ApiImplicitParam(name = "filename", value = "备份数据的名称，简称：名称。必填；120字内；前台正则校验规则，与资源库名称规则一致。", required = true),
            @ApiImplicitParam(name = "description", value = "详细说明，可以为空。")})
    public JsonResult backup(@RequestParam("filename") String filename,
                             @RequestParam(value = "description", required = false, defaultValue = "") String description) throws IOException {
        boolean backupFunc = hSFuncServiceImpl.backupFunc();
        if (!backupFunc) {
            return JsonResult.messageError("无权使用备份功能，请购买增值！");
        }
        // 判断空间是否有空间可以进行备份操作
        long space = hostSetupServiceImpl.getSpace();
        long usedSpace = hostSetupServiceImpl.getUsedSpace();
        if (usedSpace >= space) {
            return JsonResult.messageError("空间不足无法上传！");
        }

        if (StrUtil.isBlank(filename)) {
            return JsonResult.messageError("请填写名称！");
        }

        if (StrUtil.length(filename) > 120) {
            return JsonResult.messageError("填写名称长度不能超过120！");
        }
        if (StrUtil.length(description) > 1000) {
            return JsonResult.messageError("填写描述长度不能超过1000！");
        }

        // 用户操作日志写再此对方方法中
        return hostBackupRestoreServiceImpl.backup(filename, description);
    }

    /**
     * 异步还原，日志写到了 hostBackupRestoreServiceImpl 中
     */
    @PostMapping("/restore")
    @ApiOperation(value = "还原", notes = "异步，还原备份的数据，参数为备份的数据ID，返回中没有data内容。")
    @ApiImplicitParams({@ApiImplicitParam(name = "id", value = "备份数据的ID", required = true)})
    public JsonResult restore(@RequestParam("id") long hBackupId) throws IOException {
        boolean backupFunc = hSFuncServiceImpl.backupFunc();
        if (!backupFunc) {
            return JsonResult.messageError("无权使用备份功能，请购买增值！");
        }

        // 用户操作日志写再此对方方法中
        return hostBackupRestoreServiceImpl.restore(hBackupId);
    }

    @PostMapping("/isrestore")
    @ApiOperation(value = "还原中？", notes = "获取站点是否有正在执行还原的操作")
    @ApiResponses({@ApiResponse(code = 200, message = "data 返回数据字段说明。\n" + "runing：站点是否有正在执行还原的操作，0-否 1-是。\n" + "filename：正在执行还原的备份数据名。\n"
            + "expire：已经执行多长时间了。单位秒\n")})
    public JsonResult isrestore() {
        return hostBackupRestoreServiceImpl.isrestore();
    }

    @PostMapping("/delete-backup")
    @ApiImplicitParams({@ApiImplicitParam(name = "id", value = "备份数据的ID", required = true)})
    @ApiOperation(value = "删除备份", notes = "通过传入备份数据ID参数，删除对应的备份数据，可以释放空间，调用时前台给与弹窗确认删除。")
    @ApiResponses({@ApiResponse(code = 200, message = "data 返回被删除的数据表示删除成功，自动给与提示！")})
    public JsonResult deleteBackup(@RequestParam("id") long hBackupId) throws IOException {
        return hostBackupRestoreServiceImpl.deleteBackup(hBackupId);
    }

}
